package restaurant.behaviours.waiter;

import jade.core.behaviours.CyclicBehaviour;
import jade.lang.acl.ACLMessage;

import java.util.Hashtable;
import java.util.ListIterator;
import java.util.concurrent.CopyOnWriteArrayList;

import javax.swing.JOptionPane;

import restaurant.agents.WaiterAgent;
import restaurant.core.CustomizedPerformative;
import restaurant.core.Request;
import restaurant.core.Restaurant;
import restaurant.gui.Coordinate;

public class WaiterServingBehaviour extends CyclicBehaviour {

	private static final long serialVersionUID = -6867383185519329363L;
	private WaiterAgent agent;
	
	public WaiterServingBehaviour(WaiterAgent agent) {
		this.agent = agent;
	}

	@Override
	public void action() {
		if(this.agent.toDo != CustomizedPerformative.WAITER_KITCHEN_COMMUNICATION || this.agent.restaurant.readyMeals.isEmpty())
			return;

		this.agent.setFree(false);

		Request toServe = new Request(-1);
		if(this.agent.isProfessional()) {
			
			synchronized (this.agent.restaurant.readyMeals) {
				CopyOnWriteArrayList<Hashtable<Request, Boolean>> tmpList = new CopyOnWriteArrayList<Hashtable<Request,Boolean>>(this.agent.restaurant.readyMeals);
				ListIterator<Hashtable<Request, Boolean>> iterator = tmpList.listIterator();
				while(iterator.hasNext()) {
					Hashtable<Request, Boolean> tmp = iterator.next();
					Request r = tmp.keys().nextElement();
					if(toServe.getTable() == -1)
						toServe.setTable(r.getTable());
					if(toServe.getTable() == r.getTable()) {
						toServe.addMeal(r.getMeals().get(0));
						this.agent.restaurant.readyMeals.removeElement(tmp);
					}
				}
				this.agent.toDo = -1;
			}
		} else {
			synchronized (this.agent.restaurant.readyMeals) {
				CopyOnWriteArrayList<Hashtable<Request, Boolean>> tmpList = new CopyOnWriteArrayList<Hashtable<Request,Boolean>>(this.agent.restaurant.readyMeals);
				ListIterator<Hashtable<Request, Boolean>> iterator = tmpList.listIterator();
				if(iterator.hasNext()) {
					Hashtable<Request, Boolean> tmp = iterator.next();
					this.agent.restaurant.readyMeals.removeElement(tmp);
					Request r = tmp.keys().nextElement();
					toServe.setTable(r.getTable());
					toServe.addMeal(r.getMeals().get(0));
				}
				if(this.agent.restaurant.readyMeals.isEmpty() || this.agent.restaurant.readyMeals.firstElement().keys().nextElement().getTable() != toServe.getTable())
					this.agent.toDo = -1;
			}
		}

		// Serve customer at table "table"
		if(toServe.getTable() != -1) {
			ACLMessage reply = new ACLMessage(CustomizedPerformative.SERVING);
			reply.setContent(toServe.toString());
			synchronized (this.agent.restaurant.tables) {
				reply.addReceiver(this.agent.restaurant.tables.get(toServe.getTable()).getCustomer());
			}
			
			Restaurant.goTo(this.agent.me, null, this.agent.getLocalName(), this.agent.getAID(), this.agent.restaurant.tables.get(toServe.getTable()).getCoordinate());

			myAgent.send(reply);
			
			Restaurant.goTo(this.agent.me, null, this.agent.getLocalName(), this.agent.getAID(), new Coordinate(0, 1));
			
			if(this.agent.toDo == -1) {
				JOptionPane.showMessageDialog(null, "Buon Appetito!", this.agent.getLocalName(), JOptionPane.INFORMATION_MESSAGE);
				System.out.println("WaiterAgent: Tavolo " + toServe.getTable() + " servito. Buon Appetito!");

				this.agent.setFree(true);
			}
		}
	}
}